#include <sys/types.h>		//socket、connect
#include <sys/socket.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>		//strerror
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdlib.h>
#include <getopt.h>		//getopt
#include <sys/stat.h>
#include <dirent.h>
#include <fcntl.h>
#include <time.h>


int get_temperature(float *temp);

void print_usage(char *progname)
{
	printf("%s usage: \n", progname);
	printf("-i(--ipaddr): sepcify server IP address\n");
	printf("-p(--port): sepcify server port\n");
	printf("-h(--help): print this help information\n");

	return ;
}

int main(int argc, char **argv)
{
	int						sockfd = -1;
	int						rv = -1;
	struct sockaddr_in		servaddr;		//ipv4用sockaddr_in，ipv6用sockaddr_in6
	char					*servip = NULL;
	int						port = 0;		//本机字节序
	char					buf[1024];
	int                     ch;

	float       			temp;
	int     				rvv; //返回值
	time_t		    		now_time;   //定义时间变量
	char					tostr[32];
	char					totemp[32];

	struct option 			opts[] = {
		{"ipaddr", required_argument, NULL, 'i'},		
		{"port", required_argument, NULL, 'p'},			
		{"help", no_argument, NULL, 'h'},
		{NULL, 0, NULL, 0}
		
	};

	
//输入命令行解析
	while( (ch = getopt_long(argc, argv, "i:p:h", opts, NULL)) != -1 )
	{
		switch(ch)
		{
			case 'i':
					servip=optarg;
					break;

			case 'p':
					port=atoi(optarg);
					break;

			case 'h':
					print_usage(argv[0]);
					return 0;

		}
	}


	if( !servip || !port )
	{
		print_usage(argv[0]);
		return 0;
	}


//socket通信
	sockfd=socket(AF_INET, SOCK_STREAM, 0);		//创建文字描述符
	if( sockfd < 0 )
	{
		printf("Create socket failure: %s\n", strerror(errno));
		return -1;		//一般出错返回负数，成功返回0
	}
	printf("Create socket[%d] successfully!\n", sockfd);
	

	memset(&servaddr, 0, sizeof(servaddr));
	servaddr.sin_family=AF_INET;
	servaddr.sin_port=htons(port);		//(网络字节序，大端字节序)主机字节顺序转换成网络字节顺序(把一个16位数高低位互换)
	inet_aton(servip, &servaddr.sin_addr);		//把ip地址进行转换，使其能够放在四字节空间中


	rv=connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
	if( rv < 0 )
	{
		printf("connect to server[%s:%d] failure: %s\n", servip, port, strerror(errno));
		return -2;
	}
	printf("connect to server[%s:%d] successfully!\n", servip, port);


//通信内容
	while(1)
	{
			rvv = get_temperature(&temp);
			if( rvv < 0 )
			{
				printf("get_temperature fialure, return value: %d", rv);
				return -1;
			}

			time(&now_time);    //获取时间
			sprintf(tostr,"Time:%s",ctime (&now_time));
			sprintf(totemp,"Temprature:%f\n",temp);
			strcat(tostr,totemp);
			rv=write(sockfd, tostr, strlen(tostr));
			if( rv < 0 )
			{
				printf("write to server by sockfd[%d] failure: %s\n", sockfd, strerror(errno));
				break;
			}

		//读取服务端信息
		memset(buf, 0, sizeof(buf));
		rv=read(sockfd, buf, sizeof(buf));
		if( rv < 0 )
		{
			printf("Read data from server by sockfd[%d] failure: %S\n", sockfd, strerror(errno));
			break;
		}
		else if( rv == 0 )
		{
			printf("Socket[%d] get disconnected\n", sockfd);
			break;
		}
		else if( rv > 0 )
		{
			printf("Read %d bytes data from Server: %s\n", rv, buf);
		}
	sleep(10);
	}

	close(sockfd);
	
}

  
int get_temperature(float *temp)
{
	int				fd=-1;
	char			buf[128];   //一般给2的次方
	char        	*ptr = NULL;
	DIR     		*dirp = NULL;   //DIR结构体类似于FILE，是一个内部结构
	struct dirent   *direntp = NULL;    //dir结构体 
	char        	w1_path[64]="/sys/bus/w1/devices/";
	char	        chip_sn[32];
	int			    found = 0;
//	int 		    i = 0;


	dirp=opendir(w1_path);      //打开目录
	if( !dirp)
	{
		printf("open folder %s failure: %s\n", w1_path, strerror(errno));
		return -1;		
	}
 

	while( (direntp=readdir(dirp)) != NULL)
	{
		if( strstr(direntp->d_name, "28-") )    //在文件名中查找第一次出现字符串 28- 的位置，不包含终止符 '\0'
		{
			strncpy(chip_sn, direntp->d_name, sizeof(chip_sn)); //把这个名字复制到chip_sn中
			found = 1;
		}
	}
	closedir(dirp);

	if( !found )    //没找到 28- 开头文件的情况
	{
		printf("Can not find ds18b20 chipset\n");
		return -2;
	}

	strncat(w1_path, chip_sn, sizeof(w1_path)-strlen(w1_path));
    strncat(w1_path, "/w1_slave", sizeof(w1_path)-strlen(w1_path));
 
	fd=open(w1_path,O_RDONLY);
	if(fd < 0)
	{
		printf("open file failure: %s\n",strerror(errno));
		return -3;
	}

    memset(buf, 0, sizeof(buf));    //字符串以\0结尾，\0是0，初始化
	if( read(fd, buf, sizeof(buf)) < 0 )
	{
		printf("read data from fd=%d failure: %s\n", fd ,strerror(errno));
		return -4;
	} 

	ptr=strstr(buf, "t=");      //寻找文件中 t= 的内容
	if(!ptr)
	{
		printf("Can not find t= string\n");
		return -5;
	}

	ptr +=2;    //去掉“t=”，只留下温度值
	*temp = atof(ptr)/1000;     //ASCII转float

	close(fd); 
	return 0;

}
